package com.client.job.runJob;

import java.util.Date;
import java.util.List;
import javax.annotation.Resource;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.client.job.core.constant.JobReqEnums;
import com.client.job.core.model.MJob;
import com.client.job.core.model.MJobInstance;
import com.client.job.core.model.MJobVo;
import com.client.job.utils.DataResult;


/**
 * 自定义的用来处理Job的增删改查
 *
 * @author mxz
 */
@Component
@Slf4j
public class JobExcuteFactory {

    @Resource
    private JobScheduleCurd jobScheduleCurd;


    /**
     * 更具方法出来任务
     *
     * @param dataJson
     * @throws Exception
     */
    @SuppressWarnings("unchecked")
    public void dealJobByMd(String dataJson) throws Exception {

        DataResult result = JSON.parseObject(dataJson, DataResult.class);
        if (!result.isSuccess()) {
            throw new RuntimeException(result.getMessage());
        }
        List<JSONObject> obJlist = (List<JSONObject>) result.getData();
        if (result.getRequestType() == JobReqEnums.APP_COUNT_UPD.getCode()) {
            obJlist.forEach(o -> {
                try {
                    dealOne(JSON.toJavaObject(o, MJobVo.class), result.getRequestType());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }

        if (result.getRequestType() == JobReqEnums.JOB_REMOVE.getCode()) {
            obJlist.forEach(o -> {
                try {
                    dealOne(JSON.toJavaObject(o, MJobVo.class), result.getRequestType());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }

    }


    private void dealOne(MJobVo mJobVo, Integer curdFlag) {
        //变更节点
        MJob mJob = mJobVo.getMJob();
        if (curdFlag == JobReqEnums.APP_COUNT_UPD.getCode()) {
            for (MJobInstance mj : mJobVo.getMJobInstanceList()) {
                log.info("节点变更：{}", mj.getJobName());
                MJob temp = new MJob();
                BeanUtils.copyProperties(mJob, temp);
                temp.setCurrentNode(mj.getSort());
                temp.setJobName(mj.getJobName());
                updAppCounts(temp, mj);
                SystemJobs.setJob(temp);
            }
        }

        //删除节点
        if (curdFlag == JobReqEnums.JOB_REMOVE.getCode()) {
            for (MJobInstance mj : mJobVo.getMJobInstanceList()) {
                log.info("删除节点：{}", mj.getJobName());
                MJob temp = new MJob();
                BeanUtils.copyProperties(mJob, temp);
                temp.setCurrentNode(mj.getSort());
                temp.setJobName(mj.getJobName());
                removeNewJob(mJob);
                SystemJobs.removeJob(temp.getJobName());
            }
        }
    }

    /**
     * 变更节点数
     *
     * @param mJob
     * @param mJobInstance
     */
    public void updAppCounts(MJob mJob, MJobInstance mJobInstance) {
        jobScheduleCurd.removeTask(mJobInstance.getJobName());
        try {
            jobScheduleCurd.addTask(() -> {
                try {
                    JobBurstPolicy.callBack(mJob, mJobInstance);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }, new Trigger() {
                @Override
                public Date nextExecutionTime(TriggerContext triggerContext) {
                    return new CronTrigger(mJob.getCron()).nextExecutionTime(triggerContext);
                }
            }, mJob.getJobName());
        } catch (Exception e2) {
            return;
        }
    }

    /**
     * 复制一个新的Job
     *
     * @param jd
     * @throws Exception
     */
    public void copyNewJob(MJob jd, MJobInstance mJobInstance) {

        try {
            jobScheduleCurd.addTask(() -> {
                try {
                    JobBurstPolicy.callBack(jd, mJobInstance);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }, new Trigger() {
                @Override
                public Date nextExecutionTime(TriggerContext triggerContext) {
                    return new CronTrigger(jd.getCron()).nextExecutionTime(triggerContext);
                }
            }, jd.getJobName());
        } catch (Exception e2) {
            return;
        }
    }

    /**
     * 删除一个节点
     *
     * @param jd
     */
    public void removeNewJob(MJob jd) {
        jobScheduleCurd.removeTask(jd.getJobName());
        jd.setAppCounts(jd.getAppCounts() - 1);
    }

    /**
     * 修改节点
     *
     * @param jd
     */
    public void updateJob(MJob jd, MJobInstance mJobInstance) {
        try {
            jobScheduleCurd.addTask(() -> {
                try {
                    JobBurstPolicy.callBack(jd, mJobInstance);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }, new Trigger() {
                @Override
                public Date nextExecutionTime(TriggerContext triggerContext) {
                    return new CronTrigger(jd.getCron()).nextExecutionTime(triggerContext);
                }
            }, jd.getJobName());
        } catch (Exception e2) {
            return;
        }
    }


}
